package com.caiyi.financial.nirvana.sms.controller;

import com.alibaba.fastjson.JSON;
import com.caiyi.financial.nirvana.sms.cache.BlackMobileCache;
import com.caiyi.financial.nirvana.sms.cache.SmsMateCache;
import com.caiyi.financial.nirvana.sms.entity.*;
import com.caiyi.financial.nirvana.sms.enums.*;
import com.caiyi.financial.nirvana.sms.jedis.JedisKey;
import com.caiyi.financial.nirvana.sms.jedis.JedisService;
import com.caiyi.financial.nirvana.sms.service.*;
import com.youyu.common.api.Result;
import com.youyu.common.enums.BaseResultCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.crypto.hash.Hash;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * Created by Mario on 2017/12/15 0015.
 * load项目测试Controller
 */
@Api(description = "控制中心")
@RestController
@RequestMapping("/sms/admin/load")
public class SmsLoadController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());


    @Autowired
    private SmsUserService smsUserService;
    @Autowired
    private SmsKeywordService smsKeywordService;
    @Autowired
    private SmsAccountBlacklistService smsAccountBlacklistService;
    @Autowired
    private SmsBlacklistService smsBlacklistService;
    @Autowired
    private SmsGatewayService smsGatewayService;
    @Autowired
    private SmsProductService smsProductService;
    @Autowired
    private SmsUserTemplateService smsUserTemplateService;
    @Autowired
    private SmsMateService smsMateService;
    @Autowired
    private SmsUserSignService smsUserSignService;

    @Autowired
    private SmsWhiteListService smsWhiteListService;

    /**
     * 加载所有信息
     *
     * @return 操作结果
     */
    @ApiOperation(value = "加载所有信息", notes = "所有信息")
    @RequestMapping(value = "/all", method = RequestMethod.POST)
    public Object loadAll() {
        Result json = new Result();
        try {
            List<Result> ResultList = new ArrayList<>();
            Result loadAccountBlacklistJson = (Result) loadAccountBlacklist();
            ResultList.add(loadAccountBlacklistJson);
            Result loadBlacklistJson = (Result) loadBlacklist();
            ResultList.add(loadBlacklistJson);
            Result loadGatewayJson = (Result) loadGateway();
            ResultList.add(loadGatewayJson);
            Result loadProductJson = (Result) loadProduct();
            ResultList.add(loadProductJson);
            Result loadKeyWordJson = (Result) loadKeyWord();
            ResultList.add(loadKeyWordJson);
            Result loadUserJson = (Result) loadUser();
            ResultList.add(loadUserJson);
            Result loadUserTemplateJson = (Result) loadUserTemplate();
            ResultList.add(loadUserTemplateJson);
            Result loadWhiteListJson = (Result) loadWhiteList();
            ResultList.add(loadWhiteListJson);
            Result loadSignJson = (Result) loadSign();
            ResultList.add(loadSignJson);
            StringBuilder errMsg = new StringBuilder();
            for (Result item : ResultList) {
                if (item.getCode().equals(BaseResultCode.SYSTEM_ERROR.getCode())) {
                    errMsg.append(item.getDesc()).append(";");
                }
            }
            if (errMsg.length() > 0) {
                json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
                json.setDesc("loadAll error - " + errMsg.toString());
            }
        } catch (Exception e) {
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadAll error");
            logger.error("SmsLoadController loadAll error", e);
        }
        return json;
    }

    @ApiOperation(value = "加载产品信息", notes = "产品信息")
    @RequestMapping(value = "/product", method = RequestMethod.POST)
    public Object loadProduct() {
        Result json = new Result();
        Map<String, String> productMapCache = new HashMap();
        try {
            String key = String.format(JedisKey.SMS_PRODUCT, "*");
            Set<String> keys = JedisService.keys(key);
            for (String product : keys) {
                String jsonProduct = JedisService.get(product);
                productMapCache.put(product, jsonProduct);
            }
            JedisService.del(keys.toArray(new String[keys.size()]));
            List<SmsProduct> products = smsProductService.queryAll();
            for (SmsProduct product : products) {
                key = String.format(JedisKey.SMS_PRODUCT, product.getId());
                JedisService.set(key, JSON.toJSONString(product));
            }
            logger.info("loadProduct success count {}", products.size());
            productMapCache.clear();
        } catch (Exception e) {
            for (Map.Entry<String, String> entry : productMapCache.entrySet()) {
                JedisService.set(entry.getKey(), entry.getValue());
            }
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadProduct error");
            logger.error("SmsLoadController loadProduct error", e);
        }
        return json;
    }

    /**
     * 加载网关信息
     *
     * @return result
     */
    @ApiOperation(value = "加载网关信息", notes = "网关信息")
    @RequestMapping(value = "/gateway", method = RequestMethod.POST)
    public Object loadGateway() {
        Result json = new Result();
        Map<String, String> gatewayMapCache = new HashMap();
        try {
            String key = String.format(JedisKey.SMS_GATEWAY, "*");
            Set<String> keys = JedisService.keys(key);
            for (String gateway : keys) {
                String jsonGateway = JedisService.get(gateway);
                gatewayMapCache.put(gateway, jsonGateway);
            }
            JedisService.del(keys.toArray(new String[keys.size()]));
            SmsGateway bean = new SmsGateway();
            bean.setStatus(SmsGatewayStatusEnum.ENABLE.index);
            List<SmsGateway> gateways = smsGatewayService.select(bean);
            for (SmsGateway gateway : gateways) {
                key = String.format(JedisKey.SMS_GATEWAY, gateway.getId());
                JedisService.set(key, JSON.toJSONString(gateway));
            }
            logger.info("loadGateway success count {}", gateways.size());
            gatewayMapCache.clear();
        } catch (Exception e) {
            for (Map.Entry<String, String> entry : gatewayMapCache.entrySet()) {
                JedisService.set(entry.getKey(), entry.getValue());
            }
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadGateway error");
            logger.error("SmsLoadController loadGateway error", e);
        }
        return json;
    }

    /**
     * 加载关键词
     *
     * @return result
     */
    @ApiOperation(value = "加载关键词信息", notes = "关键词信息")
    @RequestMapping(value = "/keyWord", method = RequestMethod.POST)
    public Object loadKeyWord() {
        Result json = new Result();
        Map<String, Set<String>> keyWordMapCache = new HashMap();
        try {
            Set<String> jsonKeyWord = JedisService.smembers(JedisKey.SMS_KEYWORD);
            keyWordMapCache.put(JedisKey.SMS_KEYWORD, jsonKeyWord);
            JedisService.del(JedisKey.SMS_KEYWORD);
            List<SmsKeyword> keywords = smsKeywordService.queryAll();
            for (SmsKeyword keyword : keywords) {
                JedisService.sadd(JedisKey.SMS_KEYWORD, keyword.getContent());
            }
            logger.info("loadKeyWord success count {}", keywords.size());
            keyWordMapCache.clear();
        } catch (Exception e) {
            for (Map.Entry<String, Set<String>> entry : keyWordMapCache.entrySet()) {
                String[] kewWord = entry.getValue().toArray(new String[entry.getValue().size()]);
                JedisService.sadd(entry.getKey(), kewWord);
            }
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadKeyWord error");
            logger.error("SmsLoadController loadKeyWord error", e);
        }
        return json;
    }

    @ApiOperation(value = "加载账号信息", notes = "账号信息")
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public Object loadUser() {
        Result json = new Result();
        Map<String, String> userMapCache = new HashMap();
        Map<String, String> balanceMapCache = new HashMap();
        try {
            String key = String.format(JedisKey.SMS_USER, "*");
            Set<String> keys = JedisService.keys(key);
            for (String account : keys) {
                String jsonUser = JedisService.get(account);
                userMapCache.put(account, jsonUser);
            }
            JedisService.del(keys.toArray(new String[keys.size()]));
            key = String.format(JedisKey.SMS_BALANCE, "*");
            keys = JedisService.keys(key);
            for (String balance : keys) {
                String jsonBalance = JedisService.get(balance);
                balanceMapCache.put(balance, jsonBalance);
            }
            JedisService.del(keys.toArray(new String[keys.size()]));
            SmsUser userBean = new SmsUser();
            userBean.setStatus(SmsUserStatusEnum.ENABLE.index);
            List<SmsUser> smsUsers = smsUserService.select(userBean);
            for (SmsUser user : smsUsers) {
                key = String.format(JedisKey.SMS_USER, user.getAccount());
                JedisService.set(key, JSON.toJSONString(user));
                key = String.format(JedisKey.SMS_BALANCE, user.getAccount());
                JedisService.set(key, user.getSmsNum().toString());
                key = String.format(JedisKey.SMS_EXTEND_ACCOUNT, user.getExtendCode());
                JedisService.set(key, user.getAccount());
            }
            logger.info("loadUser success count {}", smsUsers.size());
            userMapCache.clear();
            balanceMapCache.clear();
        } catch (Exception e) {
            for (Map.Entry<String, String> entryUser : userMapCache.entrySet()) {
                JedisService.set(entryUser.getKey(), entryUser.getValue());
            }
            for (Map.Entry<String, String> entryBalance : balanceMapCache.entrySet()) {
                JedisService.set(entryBalance.getKey(), entryBalance.getValue());
            }
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadUser error");
            logger.error("SmsLoadController loadUser error", e);
        }
        return json;
    }

    @ApiOperation(value = "加载账号黑名单", notes = "账号黑名单")
    @RequestMapping(value = "/accountBlacklist", method = RequestMethod.POST)
    public Object loadAccountBlacklist() {
        Result json = new Result();
        Map<String, Set<String>> accountBlacklistMapCache = new HashMap();
        try {
            String key = String.format(JedisKey.SMS_BLACKLIST_ACCOUNT, "*");
            Set<String> keys = JedisService.keys(key);
            for (String accountBlacklist : keys) {
                Set<String> jsonAccountBlacklist = JedisService.smembers(accountBlacklist);
                accountBlacklistMapCache.put(accountBlacklist, jsonAccountBlacklist);
            }
            JedisService.del(keys.toArray(new String[keys.size()]));
            List<SmsAccountBlacklist> smsAccountBlacklists = smsAccountBlacklistService.queryAll();
            HashMap<String, String> map = new HashMap<>();
            for (SmsAccountBlacklist smsAccountBlacklist : smsAccountBlacklists) {
                String account = smsAccountBlacklist.getAccount();
                key = String.format(JedisKey.SMS_BLACKLIST_ACCOUNT, account);
                String phone = smsAccountBlacklist.getPhone();
                JedisService.sadd(key, phone);
                BlackMobileCache.addMobile(account, phone);
                map.put(account, phone);
            }
            //传给api內存
            map.put("method", SubscribeEnum.ADDMOBILEMAP.method);
            JedisService.publish(JedisKey.SMS_SUBSCRIBE_API_ACTION, JSON.toJSONString(map));
            logger.info("loadAccountBlacklist success count {}", smsAccountBlacklists.size());
            accountBlacklistMapCache.clear();
        } catch (Exception e) {
            for (Map.Entry<String, Set<String>> entry : accountBlacklistMapCache.entrySet()) {
                String[] phone = entry.getValue().toArray(new String[entry.getValue().size()]);
                JedisService.sadd(entry.getKey(), phone);
            }
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadAccountBlacklist error");
            logger.error("SmsLoadController loadAccountBlacklist error", e);
        }
        return json;
    }

    @ApiOperation(value = "加载白名单", notes = "加载白名单")
    @RequestMapping(value = "/loadWhiteList", method = RequestMethod.POST)
    public Object loadWhiteList() {
        Result json = new Result();
        Map<String, Set<String>> whiteListMapCache = new HashMap();
        try {
            String key = String.format(JedisKey.SMS_WHITE_LIST_ACCOUNT, "*");
            Set<String> keys = JedisService.keys(key);
            for (String whiteList : keys) {
                Set<String> jsonWhiteList = JedisService.smembers(whiteList);
                whiteListMapCache.put(whiteList, jsonWhiteList);
            }
            JedisService.del(keys.toArray(new String[keys.size()]));
            List<SmsWhiteList> whiteLists = smsWhiteListService.queryAll();
            for (SmsWhiteList whiteList : whiteLists) {
                String account = whiteList.getAccount();
                key = String.format(JedisKey.SMS_WHITE_LIST_ACCOUNT, account);
                String phone = whiteList.getPhone();
                JedisService.sadd(key, phone);
            }
            logger.info("loadWhiteList success count {}", whiteLists.size());
            whiteListMapCache.clear();
        } catch (Exception e) {
            for (Map.Entry<String, Set<String>> entry : whiteListMapCache.entrySet()) {
                String[] whiteList = entry.getValue().toArray(new String[entry.getValue().size()]);
                JedisService.sadd(entry.getKey(), whiteList);
            }
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadWhiteList error");
            logger.error("SmsLoadController loadWhiteList error", e);
        }
        return json;
    }

    @ApiOperation(value = "加载系统黑名单", notes = "系统黑名单")
    @RequestMapping(value = "/blacklist", method = RequestMethod.POST)
    public Object loadBlacklist() {
        Result json = new Result();
        Map<String, Set<String>> blacklistMapCache = new HashMap();
        try {
            Set<String> blacklist = JedisService.smembers(JedisKey.SMS_BLACKLIST);
            blacklistMapCache.put(JedisKey.SMS_BLACKLIST, blacklist);
            JedisService.del(JedisKey.SMS_BLACKLIST);
            List<SmsBlacklist> smsBlacklists = smsBlacklistService.queryAll();
            Map map = new HashMap();
            int size = smsBlacklists.size();
            String[] arr = new String[size];
            for (SmsBlacklist smsBlacklist : smsBlacklists) {
                String phone = smsBlacklist.getPhone();
                JedisService.sadd(JedisKey.SMS_BLACKLIST, phone);
                BlackMobileCache.addSysMobile(phone);
                arr[--size] = phone;
            }
            map.put("phones", arr);
            //传给api內存
            map.put("method", SubscribeEnum.ADDSYSLISTMOBILE.method);
            JedisService.publish(JedisKey.SMS_SUBSCRIBE_API_ACTION, JSON.toJSONString(map));
            logger.info("loadAccountBlacklist success count {}", smsBlacklists.size());
            blacklistMapCache.clear();
        } catch (Exception e) {
            for (Map.Entry<String, Set<String>> entryUser : blacklistMapCache.entrySet()) {
                String[] whiteList = entryUser.getValue().toArray(new String[entryUser.getValue().size()]);
                JedisService.sadd(entryUser.getKey(), whiteList);
            }
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadAccountBlacklist error");
            logger.error("SmsLoadController loadAccountBlacklist error", e);
        }
        return json;
    }

    @ApiOperation(value = "加载用户短信模板", notes = "短信模板")
    @RequestMapping(value = "/userTemplate", method = RequestMethod.POST)
    public Object loadUserTemplate() {
        Result json = new Result();
        Map<String, Set<String>> userTemplateMapCache = new HashMap();
        try {
            String key = String.format(JedisKey.SMS_TEMPLATE, "*");
            Set<String> keys = JedisService.keys(key);
            for (String userTemplate : keys) {
                Set<String> jsonUserTemplate = JedisService.smembers(userTemplate);
                userTemplateMapCache.put(userTemplate, jsonUserTemplate);
            }
            JedisService.del(keys.toArray(new String[keys.size()]));
            List<SmsUserTemplate> smsUserTemplateList = smsUserTemplateService.queryAll();
            for (SmsUserTemplate template : smsUserTemplateList) {
                if (template.getStatus() == SmsUserTempleteStatusEnum.PASS.index) {
                    key = String.format(JedisKey.SMS_TEMPLATE, template.getAccount());
                    //同一账户下，会有多个模板，添加为集合类型
                    JedisService.sadd(key, template.getTemplate());
                }
            }
            logger.info("loadUserTemplate success count {}", smsUserTemplateList.size());
            userTemplateMapCache.clear();
        } catch (Exception e) {
            for (Map.Entry<String, Set<String>> entry : userTemplateMapCache.entrySet()) {
                String[] userTemplate = entry.getValue().toArray(new String[entry.getValue().size()]);
                JedisService.sadd(entry.getKey(), userTemplate);
            }
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadUserTemplate error");
            logger.error("SmsLoadController loadUserTemplate error", e);
        }
        return json;
    }

    /**
     * 加载mate表信息到redis
     * return:
     */
    @ApiOperation(value = "加载号段到redis", notes = "号段信息")
    @RequestMapping(value = "/mate", method = RequestMethod.POST)
    public Object loadSmsMate() {
        Result json = new Result();
        try {
            long start = System.currentTimeMillis();
            List<SmsMate> smsMates = smsMateService.selectMate();
            Map<String, String> map = new HashMap<>();
            StringBuilder builder = new StringBuilder();
            for (SmsMate smsMate : smsMates) {
                builder.append(smsMate.getProvince()).append(",").append(smsMate.getCity());
                map.put(smsMate.getPhone(), builder.toString());
                builder.delete(0, builder.length());
            }
            JedisService.del(JedisKey.SMS_MATE_VALUES);
            if (!map.isEmpty()) {
                JedisService.hmset(JedisKey.SMS_MATE_VALUES, map);
                SmsMateCache.addSmsMateToLocal(map);
            }
            //传给api內存
            map.put("method", SubscribeEnum.ADDSMSMATETOLOCAL.method);
            JedisService.publish(JedisKey.SMS_SUBSCRIBE_API_ACTION, JSON.toJSONString(map));
            logger.info("loadSmsMate size : {}, cost : {} ms", map.size(), (System.currentTimeMillis() - start));
        } catch (Exception e) {
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadSmsMate error");
            logger.error("SmsLoadController loadSmsMate error", e);
        }
        return json;
    }


    @ApiOperation(value = "加载签名信息", notes = "签名信息")
    @RequestMapping(value = "/loadSign", method = RequestMethod.POST)
    public Object loadSign() {
        Result json = new Result();
        try {
            SmsUser userBean = new SmsUser();
            userBean.setStatus(SmsUserStatusEnum.ENABLE.index);
            List<SmsUser> smsUsers = smsUserService.select(userBean);
            for (SmsUser user : smsUsers) {
                smsUserSignService.updateRedis(user.getAccount());
            }
            logger.info("loadSign success count {}", smsUsers.size());
        } catch (Exception e) {
            json.setCode(BaseResultCode.SYSTEM_ERROR.getCode());
            json.setDesc("loadSign error");
            logger.error("SmsLoadController loadSign error", e);
        }
        return json;
    }
}